#include "utils/Logger.hpp"
#include <iomanip>
#include <thread>
#include <cstdlib>

namespace WaveGuard {

	// ConsoleOutput 实现
	void ConsoleOutput::write(const std::string &message) {
		std::cout << message << std::endl; // 输出到标准输出
	}

	// FileOutput 实现
	FileOutput::FileOutput(const std::string &filePath) : filePath(filePath) {
		openFile(); // 构造时打开文件
	}

	FileOutput::~FileOutput() {
		if (fileStream.is_open()) {
			fileStream.close(); // 析构时关闭文件
		}
	}

	bool FileOutput::openFile() {
		if (fileStream.is_open()) {
			fileStream.close(); // 先关闭已打开的文件
		}

		fileStream.open(filePath, std::ios::app); // 以追加模式打开文件
		return fileStream.is_open();
	}

	void FileOutput::write(const std::string &message) {
		// 如果文件未打开或打开失败，尝试重新打开
		if (!fileStream.is_open() && !openFile()) {
			std::cerr << "Failed to open log file: " << filePath << std::endl;
			return;
		}

		fileStream << message << std::endl;
		fileStream.flush(); // 确保日志立即写入文件，避免缓冲区问题
	}

	// Logger 实现
	std::shared_ptr<Logger> Logger::instance = nullptr;
	std::mutex Logger::instanceMutex;

	/**
	 * @brief 私有构造函数
	 * 初始化日志系统，默认设置为INFO级别并添加控制台输出
	 */
	Logger::Logger() : currentLevel(LogLevel::INFO),
		enableTimestamp(true),
		enableThreadId(true) {
		// 默认添加控制台输出
		addOutput(std::make_shared<ConsoleOutput>());
	}

	/**
	 * @brief 获取单例实例的静态方法
	 * 使用双重检查锁定模式确保线程安全
	 */
	std::shared_ptr<Logger> Logger::getInstance() {
		std::lock_guard<std::mutex> lock(instanceMutex);
		if (instance == nullptr) {
			instance = std::shared_ptr<Logger>(new Logger());
		}
		return instance;
	}

	/**
	 * @brief 设置日志级别
	 * @param level 新的日志级别
	 */
	void Logger::setLogLevel(LogLevel level) {
		std::lock_guard<std::mutex> lock(logMutex);
		currentLevel = level;
	}

	/**
	 * @brief 添加日志输出目标
	 * @param output 实现了LogOutput接口的输出目标
	 */
	void Logger::addOutput(std::shared_ptr<LogOutput> output) {
		std::lock_guard<std::mutex> lock(logMutex);
		outputs.push_back(output);
	}

	/**
	 * @brief 设置是否启用时间戳
	 * @param enable 启用/禁用时间戳
	 */
	void Logger::setEnableTimestamp(bool enable) {
		std::lock_guard<std::mutex> lock(logMutex);
		enableTimestamp = enable;
	}

	/**
	 * @brief 设置是否启用线程ID
	 * @param enable 启用/禁用线程ID
	 */
	void Logger::setEnableThreadId(bool enable) {
		std::lock_guard<std::mutex> lock(logMutex);
		enableThreadId = enable;
	}

	/**
	* @brief 设置是否输出到控制台
	* @param enable 启用/禁用输出到控制台
	*/
	void Logger::setConsoleOutputEnabled(bool enabled) {
		consoleOutputEnabled = enabled;

		// 检查是否需要添加或移除控制台输出
		bool hasConsoleOutput = false;
		for (auto &output : outputs) {
			if (dynamic_cast<ConsoleOutput *>(output.get())) {
				hasConsoleOutput = true;
				break;
			}
		}

		if (enabled && !hasConsoleOutput) {
			addOutput(std::make_shared<ConsoleOutput>());
		} else if (!enabled && hasConsoleOutput) {
			// 移除控制台输出
			std::vector<std::shared_ptr<LogOutput>> newOutputs;
			for (auto &output : outputs) {
				if (!dynamic_cast<ConsoleOutput *>(output.get())) {
					newOutputs.push_back(output);
				}
			}
			outputs = std::move(newOutputs);
		}
	}

	/**
	 * @brief 记录DEBUG级别日志
	 * @param message 日志消息
	 */
	void Logger::debug(const std::string &message) {
		if (currentLevel > LogLevel::DEBUG) return;

		std::lock_guard<std::mutex> lock(logMutex);
		for (auto &output : outputs) {
			output->write(formatMessage(LogLevel::DEBUG, message));
		}
	}

	/**
	 * @brief 记录INFO级别日志
	 * @param message 日志消息
	 */
	void Logger::info(const std::string &message) {
		if (currentLevel > LogLevel::INFO) return;

		std::lock_guard<std::mutex> lock(logMutex);
		for (auto &output : outputs) {
			output->write(formatMessage(LogLevel::INFO, message));
		}
	}

	/**
	 * @brief 记录WARNING级别日志
	 * @param message 日志消息
	 */
	void Logger::warning(const std::string &message) {
		if (currentLevel > LogLevel::WARNING) return;

		std::lock_guard<std::mutex> lock(logMutex);
		for (auto &output : outputs) {
			output->write(formatMessage(LogLevel::WARNING, message));
		}
	}

	/**
	 * @brief 记录ERROR级别日志
	 * @param message 日志消息
	 */
	void Logger::error(const std::string &message) {
		if (currentLevel > LogLevel::ERROR)  ;

		std::lock_guard<std::mutex> lock(logMutex);
		for (auto &output : outputs) {
			output->write(formatMessage(LogLevel::ERROR, message));
		}
	}

	/**
	 * @brief 记录CRITICAL级别日志
	 * @param message 日志消息
	 */
	void Logger::critical(const std::string &message) {
		if (currentLevel > LogLevel::CRITICAL) return;

		std::lock_guard<std::mutex> lock(logMutex);
		for (auto &output : outputs) {
			output->write(formatMessage(LogLevel::CRITICAL, message));
		}
	}

	/**
	 * @brief 格式化完整的日志消息
	 * @param level 日志级别
	 * @param message 原始日志消息
	 * @return 格式化后的完整日志消息
	 */
	std::string Logger::formatMessage(LogLevel level, const std::string &message) {
		std::stringstream ss;

		// 根据配置添加时间戳
		if (enableTimestamp) {
			ss << "[" << getTimestamp() << "] ";
		}

		// 根据配置添加线程ID
		if (enableThreadId) {
			ss << "[" << getThreadId() << "] ";
		}

		// 添加日志级别和原始消息
		ss << "[" << getLevelString(level) << "] " << message;
		return ss.str();
	}

	/**
	 * @brief 获取日志级别的字符串表示
	 * @param level 日志级别
	 * @return 对应的字符串
	 */
	std::string Logger::getLevelString(LogLevel level) {
		switch (level) {
		case LogLevel::DEBUG:    return "DEBUG";
		case LogLevel::INFO:     return "INFO";
		case LogLevel::WARNING:  return "WARNING";
		case LogLevel::ERROR:    return "ERROR";
		case LogLevel::CRITICAL: return "CRITICAL";
		default:                 return "UNKNOWN";
		}
	}

	/**
	 * @brief 获取当前时间戳的字符串表示
	 * @return 格式化的时间戳字符串
	 */
	std::string Logger::getTimestamp() {
		auto now = std::chrono::system_clock::now();
		auto now_c = std::chrono::system_clock::to_time_t(now);

		std::stringstream ss;
		ss << std::put_time(std::localtime(&now_c), "%Y-%m-%d %H:%M:%S");

		// 添加毫秒部分
		auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
		auto ms = now_ms.time_since_epoch() % std::chrono::seconds(1);
		ss << "." << std::setfill('0') << std::setw(3) << ms.count();

		return ss.str();
	}

	/**
	 * @brief 获取当前线程ID的字符串表示
	 * @return 线程ID字符串
	 */
	std::string Logger::getThreadId() {
		std::stringstream ss;
		ss << std::this_thread::get_id();
		return ss.str();
	}

} // namespace WaveGuard